package com.example.bookkeepingelf.business.database.service.impl;

import android.util.Log;
import android.widget.TextView;

import com.example.bookkeepingelf.R;
import com.example.bookkeepingelf.business.constant.AccountBookConstant;
import com.example.bookkeepingelf.business.database.service.CalculatorService;
import com.example.bookkeepingelf.business.enums.JsqNumberToResourceIdEnum;
import com.example.bookkeepingelf.business.enums.JsqOperatorToResourceIdEnum;

import java.math.BigDecimal;
import java.util.Objects;
public class CalculatorServiceImpl implements CalculatorService {

    private static final int MINI_DROP = R.id.jsq_mini_drop;



    private TextView textView;



    @Override
    public String convertTextResult(TextView showTextView, int clickViewId) {
        this.baseValidate(showTextView);
        this.textView = showTextView;
        //获取文本
        String beforeStrValue = this.getStringValue(showTextView);
        StringBuilder resultSb = new StringBuilder(beforeStrValue);

        //判断是否为操作符
        if (JsqOperatorToResourceIdEnum.getMathsOperatorResourceIdList().contains(clickViewId)) {
            resultSb = this.operatorHandle(resultSb, beforeStrValue, clickViewId);
        }else if (MINI_DROP == clickViewId){
            //小数点处理
            resultSb = this.miniDropHandle(resultSb, beforeStrValue);
        }else if (JsqNumberToResourceIdEnum.getNumberResourceIdList().contains(clickViewId)){
            //数字处理
            resultSb = this.numberHandle(resultSb, beforeStrValue, clickViewId);
        }else {
            throw new RuntimeException("clickViewId is error");
        }
        if (Objects.isNull(resultSb)) {
            return null;
        }
        return resultSb.toString();
    }

    private StringBuilder operatorHandle(StringBuilder resultSb, String beforeStrValue, int clickViewId) {
        JsqOperatorToResourceIdEnum operatorToResourceIdEnum = JsqOperatorToResourceIdEnum.getJsqOperatorToResourceIdEnumById(clickViewId);
        if (Objects.isNull(operatorToResourceIdEnum)) {
            throw new RuntimeException("operatorToResourceIdEnum is null");
        }
        //是否是
        if (operatorToResourceIdEnum.equals(JsqOperatorToResourceIdEnum.OPERATOR_EQ)) {
            //直接按照操作符分割
            BigDecimal result = this.buildResult(beforeStrValue);
            if (Objects.isNull(result)) {
                return null;
            }
            this.cleanResult(resultSb);
            return this.appendStr(resultSb, result.toString());
        }

        if (this.isHaveOperator(beforeStrValue)) {
            //含有操作符
            if (this.lastHaveOperator(beforeStrValue)) {
                //删除最后一位
                String s = this.removeOne(this.textView);
                return new StringBuilder(s).append(operatorToResourceIdEnum.getOperator());
            }
            //是否在第一位并且是负数
            if (this.firstHaveOperator(beforeStrValue)) {
                if (beforeStrValue.charAt(0) == '-') {
                    //是否已经包含两个操作符
                    int optNumber = this.operatorNumber(beforeStrValue);
                    if (optNumber < 2) {
                        return this.appendStr(resultSb, operatorToResourceIdEnum.getOperator());
                    }
                }else {
                    return null;
                }
            }

            BigDecimal result = this.buildResult(beforeStrValue);
            if (Objects.isNull(result)) {
                return null;
            }
            this.cleanResult(resultSb);
            return this.appendStr(resultSb, result.toString());

        }else {
            //不包含操作符

            //最后一位是否是小数点
            if (this.lastHaveMiniDrop(beforeStrValue)) {
                return null;
            }
            return this.appendStr(resultSb, operatorToResourceIdEnum.getOperator());
        }

    }

    private BigDecimal buildResult(String beforeStrValue) {
        //最后一位不是操作符(说明中间有操作符)
        //计算
        BigDecimal number1 = BigDecimal.ZERO;
        BigDecimal number2 = BigDecimal.ZERO;
        JsqOperatorToResourceIdEnum opEnum = null;
        for (JsqOperatorToResourceIdEnum value : JsqOperatorToResourceIdEnum.values()) {
            String op = value.getOperator();
            if (beforeStrValue.contains(op)) {
                //拆分
                String[] split = beforeStrValue.split(op);
                number1 = new BigDecimal(split[0]);
                number2 = new BigDecimal(split[1]);
                if (value.equals(JsqOperatorToResourceIdEnum.OPERATOR_DIV) && number2.compareTo(BigDecimal.ZERO) == 0) {
                    return AccountBookConstant.ZERO;
                }
                opEnum = value;
            }
        }
        //计算结果
        if (Objects.isNull(opEnum)) {
            return null;
        }
        BigDecimal calculate = this.calculate(number1, number2, opEnum);
        return calculate;
    }


    /**
     * 数字处理
     * @param resultSb
     * @param beforeStrValue
     * @param clickViewId
     * @return
     */
    private StringBuilder numberHandle(StringBuilder resultSb, String beforeStrValue, int clickViewId) {
        //数字
        //获取数字
        JsqNumberToResourceIdEnum numberEnum = JsqNumberToResourceIdEnum.getEnumById(clickViewId);
        if (Objects.isNull(numberEnum)) {
            throw new RuntimeException("numberEnum is null");
        }
        //判断之前的文本是否含有操作符
        if (this.isHaveOperator(beforeStrValue)) {
            int i = miniDropAfter((beforeStrValue));
            Log.i("numberHandle1111", "numberHandle: " + i);
            if (i >= 2) {
                //已经有小数点点并且有操作符（判断小数点后面是否有操作符）
                String[] split = beforeStrValue.split("\\.");
                if (!this.isHaveOperator(split[1])) {
                    return null;
                }
                if (this.lastHaveOperator(beforeStrValue)) {
                    return this.appendStr(resultSb, numberEnum.getNumberStr());
                }
                String opt = "";
                for (JsqOperatorToResourceIdEnum value : JsqOperatorToResourceIdEnum.values()) {
                    if (beforeStrValue.contains(value.getOperator())) {
                        opt = value.getOperator();
                    }
                }
                String[] split1 = beforeStrValue.split(opt);
                int i2 = miniDropAfter((split1[1]));
                if (i2 >=2) {
                    return null;
                }
                return this.appendStr(resultSb, numberEnum.getNumberStr());
            }
            return this.appendStr(resultSb, numberEnum.getNumberStr());
        }else {
            //是否为纯数字
            if (this.isHaveMiniDrop(beforeStrValue)) {
                //含有小数点
                int number = this.miniDropAfter(beforeStrValue);
                if (number >= 2) {
                    //小数点后面两位以上
                    BigDecimal inputNumber = new BigDecimal(beforeStrValue);
                    if (inputNumber.compareTo(BigDecimal.ZERO) == 0) {
                        //之前输入为0, 直接删除之前的0
                        resultSb.delete(0, resultSb.length());
                        return this.appendStr(resultSb, numberEnum.getNumberStr());
                    }
                    return null;
                }
            }else {
                //纯数字
                BigDecimal beforeNumber = new BigDecimal(beforeStrValue);
                if (beforeNumber.compareTo(BigDecimal.ZERO) == 0) {
                    //之前输入为0, 直接删除之前的0
                    resultSb.delete(0, resultSb.length());
                }
            }

            return this.appendStr(resultSb, numberEnum.getNumberStr());
        }

    }



    /**
     * 小数点处理
     * @param resultSb
     * @param beforeStrValue
     * @return
     */
    private StringBuilder miniDropHandle(StringBuilder resultSb, String beforeStrValue) {
        //之前输入是否包含小数点
        if (beforeStrValue.contains(MINI_DROP_STR)) {
            //判断是否包含操作符
            if (this.isHaveOperator(beforeStrValue)) {
                //最后一位是否含有操作符
                if (this.lastHaveOperator(beforeStrValue)) {
                    return null;
                }
                String operatorAfterStr = "";
                for (String operator : JsqOperatorToResourceIdEnum.getMathsOperatorList()) {
                    if (beforeStrValue.contains(operator)) {
                        operatorAfterStr = beforeStrValue.split(operator)[1];
                        break;
                    }
                }
                if (operatorAfterStr.contains(MINI_DROP_STR)) {
                    return null;
                }
//                int miniDropNumber = this.miniDropNumber(beforeStrValue);
//                if (miniDropNumber >= 2) {
//                    return null;
//                }
                if (this.lastHaveMiniDrop(beforeStrValue)) {
                    return null;
                }
                return this.appendStr(resultSb,MINI_DROP_STR);

            }
            return null;
        }else {
            if (lastHaveOperator(beforeStrValue)) {
                return null;
            }
        }
        resultSb = this.appendStr(resultSb,MINI_DROP_STR);

        return resultSb;
    }



    private StringBuilder appendStr(StringBuilder resultSb, String str) {
        return resultSb.append(str);
    }


    /**
     * 删除一位
     * @param textView
     * @return
     */
    @Override
    public String removeOne(TextView textView) {
        this.baseValidate(textView);
        String strValue = this.getStringValue(textView);
        Log.i("removeOne", "removeOne: " + strValue);
        if (strValue.length() == 1) {
            return AccountBookConstant.ZERO_STR;
        }

        if (!this.isHaveOperator(strValue)) {
            //是否纯数字
            if (isHaveMiniDrop(strValue)) {
                if (new BigDecimal(strValue).compareTo(BigDecimal.ZERO) == 0) {
                    return AccountBookConstant.ZERO_STR;
                }
            }
        }
        return strValue.substring(0, strValue.length() - 1);
    }

    @Override
    public String getStringValue(TextView textView) {
        return CalculatorService.super.getStringValue(textView);
    }

    @Override
    public BigDecimal calculate(BigDecimal number1, BigDecimal number2, JsqOperatorToResourceIdEnum iEnum) {
        return CalculatorService.super.calculate(number1, number2, iEnum);
    }

    @Override
    public int miniDropAfter(String beforeStrValue) {
        return CalculatorService.super.miniDropAfter(beforeStrValue);
    }

    @Override
    public boolean isHaveMiniDrop(String strValue) {
        return CalculatorService.super.isHaveMiniDrop(strValue);
    }

    @Override
    public boolean lastHaveMiniDrop(String beforeStrValue) {
        return CalculatorService.super.lastHaveMiniDrop(beforeStrValue);
    }

    @Override
    public boolean lastHaveOperator(String beforeStrValue) {
        return CalculatorService.super.lastHaveOperator(beforeStrValue);
    }

    @Override
    public boolean firstHaveOperator(String beforeStrValue) {
        return CalculatorService.super.firstHaveOperator(beforeStrValue);
    }

    @Override
    public String getLastSrt(String beforeStrValue) {
        return CalculatorService.super.getLastSrt(beforeStrValue);
    }

    @Override
    public void cleanResult(StringBuilder stringBuilder) {
        CalculatorService.super.cleanResult(stringBuilder);
    }

    @Override
    public boolean isHaveOperator(String strValue) {
        return CalculatorService.super.isHaveOperator(strValue);
    }

    @Override
    public void baseValidate(TextView showTextView) {
        CalculatorService.super.baseValidate(showTextView);
    }

    @Override
    public int operatorNumber(String beforeStrValue) {
        return CalculatorService.super.operatorNumber(beforeStrValue);
    }

    @Override
    public int miniDropNumber(String beforeStrValue) {
        return CalculatorService.super.miniDropNumber(beforeStrValue);
    }
}
